package com.wsoft.hr.pm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.entity.BaseEntity;
import com.wsoft.hr.pm.constant.HrPmTargetGroupConstant;
import com.wsoft.hr.pm.entity.HrPmTargetGroupEntity;
import com.wsoft.hr.pm.manager.HrPmTargetGroupManager;
import com.wsoft.hr.pm.manager.HrPmTargetManager;
import com.wsoft.hr.pm.mapper.HrPmTargetGroupMapper;
import com.wsoft.hr.pm.query.target.group.TargetGroupInsertQuery;
import com.wsoft.hr.pm.query.target.group.TargetGroupTreeQuery;
import com.wsoft.hr.pm.query.target.group.TargetGroupUpdateQuery;
import com.wsoft.hr.pm.service.IHrPmTargetGroupService;
import com.wsoft.hr.pm.vo.target.group.TargetGroupTreeVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 指标分组 服务实现类
 * </p>
 *
 * @author Z001
 * @since 2025年02月17日 15:07:36
 */
@Service
public class HrPmTargetGroupServiceImpl extends ServiceImpl<HrPmTargetGroupMapper, HrPmTargetGroupEntity> implements IHrPmTargetGroupService {

    @Resource
    private HrPmTargetGroupManager targetGroupManager;
    @Resource
    private HrPmTargetManager targetManager;


    @Override
    public boolean insertGroup(TargetGroupInsertQuery query) {
        HrPmTargetGroupEntity groupEntity = Convert.convert(HrPmTargetGroupEntity.class, query);
        groupEntity.setHrOrgId(LoginUserUtil.getUserInfo().getHrOrgId());
        checkGroupName(query.getName(),null);
        return targetGroupManager.save(groupEntity);
    }

    @Override
    public boolean updateGroup(TargetGroupUpdateQuery query) {
        HrPmTargetGroupEntity groupEntity = this.get(query.getId());
        //校验
        checkOrgId(groupEntity.getHrOrgId());
        checkGroupName(query.getName(),query.getId());
        HrPmTargetGroupEntity convert = Convert.convert(HrPmTargetGroupEntity.class, query);
        return targetGroupManager.updateById(convert);
    }

    @Override
    public HrPmTargetGroupEntity get(Long id) {
        return  targetGroupManager.getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        if(Objects.equals(id, HrPmTargetGroupConstant.HR_PM_DELETE_GROUP_DEFAULT)){
            //未0 默认为 未分组,不能删除
            Asserts.fail("[hr.pm.group.id.error]");
        }
        HrPmTargetGroupEntity groupEntity = targetGroupManager.getById(id);
        //校验
        checkOrgId(groupEntity.getHrOrgId());
        boolean b = targetGroupManager.removeById(id);
        //级联删除
        List<Long> idList = new ArrayList<>();
        idList.add(id);
        List<HrPmTargetGroupEntity> children = findChildren(id);
        if(CollUtil.isNotEmpty(children)){
            List<Long> list = children.stream().map(BaseEntity::getId).collect(Collectors.toList());
            targetGroupManager.removeByIds(list);
            idList.addAll(list);
        }
        if(b){
            targetManager.updateGroupIdToNull(idList);
        }
        return b;
    }

    @Override
    public List<TargetGroupTreeVO> tree(TargetGroupTreeQuery query) {
        List<HrPmTargetGroupEntity> list = targetGroupManager.listAll();
        if(StrUtil.isNotBlank(query.getName())){
            list = list.stream().filter(item -> item.getName().contains(query.getName())).collect(Collectors.toList());
        }
        List<TargetGroupTreeVO> collect = list.stream().map(item -> Convert.convert(TargetGroupTreeVO.class, item)).collect(Collectors.toList());
        return  buildTree(collect);
    }


    // ################################## 私有方法  ##################################



    /**
     * 查找给定ID的所有子集数据
     *
     * @param id 给定的ID
     * @return 所有子集的TargetGroup列表
     */
    public List<HrPmTargetGroupEntity> findChildren(Long id) {
        List<HrPmTargetGroupEntity> children = new ArrayList<>();
        List<HrPmTargetGroupEntity> list = targetGroupManager.listAll();
        // 递归查找子集
        findChildrenRecursive(id, children,list);
        return children;
    }

    /**
     * 递归查找子集
     *
     * @param parentId 父ID
     * @param children 存储子集的列表
     */
    private void findChildrenRecursive(Long parentId, List<HrPmTargetGroupEntity> children, List<HrPmTargetGroupEntity> list) {
        for (HrPmTargetGroupEntity group : list) {
            if (Objects.equals(group.getpId(), parentId)) {
                // 添加当前子集
                children.add(group);
                // 递归查找子集的子集
                findChildrenRecursive(group.getId(), children,list);
            }
        }
    }
    /**
     * 判断orgId 是否为当前登录用的orgId
     * @param orgId
     */
    private void checkOrgId(Long orgId){
        Long curOrgId = LoginUserUtil.getUserInfo().getHrOrgId();
        if(null == orgId || !orgId.equals(curOrgId)){
            //非当前组织分组 不能删除
            Asserts.fail("[hr.pm.group.orgId.error]");
        }
    }

    /**
     * 校验分组名称
     * @param name
     * @param id
     */
    private void checkGroupName(String name,Long id){
        HrPmTargetGroupEntity orgAndName = targetGroupManager.getOrgAndName(name);
        if(null == id && null != orgAndName){
            Asserts.fail("[hr.pm.name.error]");
        }
        if(null != id && null != orgAndName && !id.equals(orgAndName.getId())){
            Asserts.fail("[hr.pm.name.error]");
        }
    }


    /**
     * 构建树
     * @param nodes
     * @return
     */
    private static List<TargetGroupTreeVO> buildTree(List<TargetGroupTreeVO> nodes) {
        Map<Long, TargetGroupTreeVO> nodeMap = new HashMap<>(16);
        List<TargetGroupTreeVO> roots = new ArrayList<>();


        //将所有节点放入map中
        for (TargetGroupTreeVO node : nodes) {
            nodeMap.put(node.getId(), node);
        }

        //构建树结构
        for (TargetGroupTreeVO node : nodes) {
            if (node.getPId() == null || node.getPId() == 0 || !nodeMap.containsKey(node.getPId())) {
                // 如果没有父节点或者父节点不在map中，说明是根节点
                roots.add(node);
            } else {
                // 否则，找到父节点并将当前节点添加到父节点的children中
                TargetGroupTreeVO parent = nodeMap.get(node.getPId());
                if(null == parent.getChildren()){
                    List<TargetGroupTreeVO> arr = new ArrayList<>();
                    arr.add(node);
                    parent.setChildren(arr);
                }else{
                    List<TargetGroupTreeVO> children = parent.getChildren();
                    children.add(node);
                    parent.setChildren(children);
                }
            }
        }
        return roots;
    }


}
